import javax.xml.stream.events.EndDocument;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/*
{
(0, 12):1,  1  1  2    所有初始状态必须从1开始，其余状态一次+1
(0, 16):2,  1  4  3    DFA1的单边事件也必须从1开始：1 = 12    2 = 13    3 = 15     4 = 16   5 = 17  ...5=18  6=15 7=19 8=20
(1, 12):3,  2  1  4    DFA2的单边事件跟着续上：    6 = 14   7 = 18  8 = 19
(1, 13):0,  2  2  1    若有DFA1和DFA2共同发生的事件：就从DFA1的最后一个事件+1，则DFA2的事件变为  DFA1的事件  +  共同事件  +1 = DFA2的事件数
(1, 15):0,  2  3  1
(1, 16):4,  2  4  5
(2, 12):4,
(2, 17):0,  3  5  1
(3, 13):1,
(3, 15):1,
(3, 16):5,
(4, 12):5,
(4, 13):2,
(4, 15):2,
(4, 17):1,
(5, 13):4,
(5, 15):4,
(5, 17):3}

1  6  2
1  7  2
2  8  1
 */
public class Main {
    public static String matchEvents(String s,int way){
        switch(way){
            case 1:
                s = s+"12";break;
            case 2:
                s = s+"13";break;
            case 3:
                s = s+"15";break;
            case 4:
                s = s+"16";break;
            case 5:
                s = s+"17";break;
            case 6:
                s = s+"14";break;
            case 7:
                s = s+"18";break;
            case 8:
                s = s+"19";break;
            default:
                break;
        }
        return s;
    }
    public static void main(String[] args) throws IOException {
        //事件发生数
        int numEventA1 = 18;
        int numEventA2 = 3;
        int[][] DFA1 = new int[numEventA1][3];
        int[][] DFA2 = new int[numEventA2][3];
        //事件个数
        int dfa1NumberofSingle = 5;
        int dfa2NumberofSingle = 3;
        int midNumberofCommon = 0;

        String s = "";
        // 1 = 13 2 = 14 3 = 16...5=18  6=15 7=19 8=20
        //临时变
        DFA1[0][0] = 1;
        DFA1[0][1] = 1;
        DFA1[0][2] = 2;

        DFA1[1][0] = 1;
        DFA1[1][1] = 4;
        DFA1[1][2] = 3;

        DFA1[2][0] = 2;
        DFA1[2][1] = 1;
        DFA1[2][2] = 4;

        DFA1[3][0] = 2;
        DFA1[3][1] = 2;
        DFA1[3][2] = 1;

        DFA1[4][0] = 2;
        DFA1[4][1] = 3;
        DFA1[4][2] = 1;

        DFA1[5][0] = 2;
        DFA1[5][1] = 4;
        DFA1[5][2] = 5;

        DFA1[6][0] = 3;
        DFA1[6][1] = 1;
        DFA1[6][2] = 5;

        DFA1[7][0] = 3;
        DFA1[7][1] = 5;
        DFA1[7][2] = 1;

        DFA1[8][0] = 4;
        DFA1[8][1] = 2;
        DFA1[8][2] = 2;

        DFA1[9][0] = 4;
        DFA1[9][1] = 3;
        DFA1[9][2] = 2;

        DFA1[10][0] = 4;
        DFA1[10][1] = 4;
        DFA1[10][2] = 6;

        DFA1[11][0] = 5;
        DFA1[11][1] = 1;
        DFA1[11][2] = 6;

        DFA1[12][0] = 5;
        DFA1[12][1] = 2;
        DFA1[12][2] = 3;

        DFA1[13][0] = 5;
        DFA1[13][1] = 3;
        DFA1[13][2] = 3;

        DFA1[14][0] = 5;
        DFA1[14][1] = 5;
        DFA1[14][2] = 2;

        DFA1[15][0] = 6;
        DFA1[15][1] = 2;
        DFA1[15][2] = 5;

        DFA1[16][0] = 6;
        DFA1[16][1] = 3;
        DFA1[16][2] = 5;

        DFA1[17][0] = 6;
        DFA1[17][1] = 5;
        DFA1[17][2] = 4;

        //DFA2初始化
        DFA2[0][0] = 1;
        DFA2[0][1] = 6;
        DFA2[0][2] = 2;

        DFA2[1][0] = 1;
        DFA2[1][1] = 7;
        DFA2[1][2] = 2;

        DFA2[2][0] = 2;
        DFA2[2][1] = 8;
        DFA2[2][2] = 1;

        //终止状态初始化
        int dfa1FinalState = 1;
        int dfa2FinalState = 2;
        //矩阵的遍历模板
        System.out.println("DFA1:");
        showStateMAIN(DFA1);
        System.out.println("DFA2:");
        showStateMAIN(DFA2);
        //创建ArrayList
        //Xnew
        ArrayList<xBuf> Xnew = new ArrayList();

        LinkedList<xBuf> X = new LinkedList<>();
        //确定初态
        xBuf x0 = new xBuf(DFA1[0][0], DFA2[0][0]);
        //添加展示集合
        ArrayList<showState> show = new ArrayList();
        //添加展示头
        xBuf start;

        Xnew.add(x0);
        X.add(x0);

        //定义临时存储
        xBuf buf;
        //定义X1状态  X2状态
        Integer x1;
        Integer x2;
        //xBuf
        xBuf start1;
        xBuf end;
        //加入Xnew
        while (Xnew != null || Xnew.size() > 0) {
            //判断abc'三个字符
            for (int i = 0; i < X.size(); i++) {
                start = X.get(i);
                buf = X.get(i);
                //得到当前状态的集合的小集合状态
                x1 = buf.getX1();
                x2 = buf.getX2();
                //输入单边字符数，循环控制，for  的执行次数就是字符个数，for的每个i有一个
                for (int j = 1; j < dfa1NumberofSingle+1; j++) {
                    //DFA1单边事件  查询
                    singleA(DFA1,x1,x2,j,X,start,show,Xnew);
                    //int [][]DFA,int x1,int x2,int a,ArrayList X,xBuf start,ArrayList show,ArrayList Xnew
                }
                //公共事件
                publicEvents(dfa1NumberofSingle,DFA1,DFA2,x1,x2,midNumberofCommon,show,start,X,Xnew);
                for (int j = midNumberofCommon+dfa1NumberofSingle+1 ; j < midNumberofCommon+dfa2NumberofSingle +dfa1NumberofSingle+1 ; j++) {
                    singleB(DFA2,x1,x2,j,X,start,show,Xnew);
                }
                //每回减去一个Xnew
                Xnew.remove(0);
                //若Xnew为空则展示所有，和关闭程序
                if (Xnew.size() == 0) {
                    fileWrite.writeTXTInial("F://","TEST2");
                    for (int j = 0; j < show.size(); j++) {
                        //show里面showState对象showState{start=xBuf{x1=2, x2=2}, way='b', end=xBuf{x1=1, x2=3}}
                        // 0 -> 1 [label= 1 ];
                        start1 = show.get(j).getStart();
                        end = show.get(j).getEnd();
                        //传入方法
                        int way = show.get(j).getWay();
                        s = matchEvents(s, way);
                        String sb = (start1.getID() + 1) + " -> " + (check(end, X) + 1) + "  [label= " + s + "];";
                        //打印输出
                        fileWrite.write(sb);
                        System.out.println((start1.getID() + 1) + " -> " + (check(end, X) + 1) + "  [label= " + s + "];");
                        s = "";
                    }
                    //打印输出状态信息
                    fileWrite.write("新生成的状态集的总数："+X.size());
                    fileWrite.write("初始状态："+"{"+X.get(0).getX1()+","+X.get(0).getX1()+"}");
                    for (int j = 0; j < X.size(); j++) {
                        if(X.get(j).getX1() == dfa1FinalState || X.get(j).getX2() == dfa2FinalState){
                            s = "此状态为final";
                        }
                        fileWrite.write("状态："+"{"+X.get(j).getX1()+","+X.get(j).getX2()+"}"+s);
                        s = "";
                    }

                    fileWrite.writeClose();
                    return;
                }
            }

        }
    }


    public static void publicEvents(int dfa1NumberofSingle,
                                    int [][]DFA1,int [][] DFA2,int x1,int x2,int b,
                                    ArrayList show,xBuf start,LinkedList X,ArrayList Xnew){
        for (int i = dfa1NumberofSingle+1; i < b+dfa1NumberofSingle+1; i++) {
            for (int j = 0; j < DFA1.length; j++) {
                if (DFA1[j][0] != x1)//找对应的状态
                    continue;
                if (DFA1[j][1] != i)//找对应的字符
                    continue;
                for (int k = 0; k < DFA2.length; k++) {
                    if (DFA2[k][0] != x2)//找对应的状态
                        continue;
                    if (DFA2[k][1] != i)//找对应的字符
                        continue;
                    xBuf Xmember = new xBuf(DFA1[j][2], DFA2[k][2]);
                    show.add(new showState(start, i, Xmember));
                    if (Xmember.isPossessState(DFA1[j][2], DFA2[k][2], Xmember, X)) {
                        Xnew.add(Xmember);
                        Xmember.setID();
                    }
                    break;
                }
                break;
            }
        }

    }

    public static void singleA(int[][] DFA, int x1, int x2, int a, LinkedList X, xBuf start, ArrayList show, ArrayList Xnew) {
        for (int j = 0; j < DFA.length; j++) {
            if (DFA[j][0] != x1)//找对应的状态   改
                continue;
            if (DFA[j][1] != a)//找对应的字符
                continue;
            //将第二状态存储      改
            xBuf Xmember = new xBuf(DFA[j][2], x2);
            //添加至展示集合
            show.add(new showState(start, a, Xmember));
            //判断Xmember在X集合中是否存在，若存在加入X和Xnew中   改
            if (Xmember.isPossessState(DFA[j][2], x2, Xmember, X)) {
                Xnew.add(Xmember);
                Xmember.setID();
            }
            break;
        }
    }
    public static void singleB(int[][] DFA, int x1, int x2, int a, LinkedList X, xBuf start, ArrayList show, ArrayList Xnew) {
        for (int j = 0; j < DFA.length; j++) {
            if (DFA[j][0] != x2)//找对应的状态   改
                continue;
            if (DFA[j][1] != a)//找对应的字符
                continue;
            //将第二状态存储      改
            xBuf Xmember = new xBuf(x1, DFA[j][2]);
            //添加至展示集合
            show.add(new showState(start, a, Xmember));
            //判断Xmember在X集合中是否存在，若存在加入X和Xnew中   改
            if (Xmember.isPossessState(x1, DFA[j][2], Xmember, X)) {
                Xnew.add(Xmember);
                Xmember.setID();
            }
            break;
        }
    }


    public static void showStateMAIN(int[][] arr) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                System.out.print(arr[i][j] + "  ");
            }
            System.out.println("");
        }
    }

    public static int check(xBuf end, LinkedList X) {
        Integer endX1 = end.getX1();
        Integer endX2 = end.getX2();
        for (int i = 0; i < X.size(); i++) {
            xBuf o = (xBuf) X.get(i);
            Integer x1 = o.getX1();
            Integer x2 = o.getX2();
            if (x1 == endX1 && x2 == endX2)
                return o.getID();
        }
        return 0;
    }
}
